package com.sloth.bear.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sloth.bear.dto.base.ResponsePage;
import com.sloth.bear.dto.entity.Moment;
import com.sloth.bear.dto.request.MomentListRequest;
import com.sloth.bear.dto.request.MomentRequest;
import com.sloth.bear.dto.vo.MomentVo;
import com.sloth.bear.dto.vo.MomentsFilterVo;
import com.sloth.bear.dto.vo.moments.CreatedTimeListVo;
import com.sloth.bear.mapper.MomentMapper;
import com.sloth.bear.service.MomentService;
import com.sloth.bear.util.AssertUtils;
import com.sloth.bear.util.BaseHelper;
import com.sloth.bear.util.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class MomentServiceImpl extends ServiceImpl<MomentMapper, Moment> implements MomentService {

    @Override
    public Long createMoment(MomentRequest request) {
        Moment moment = BaseHelper.r2t(request, Moment.class);
        moment.setUserId(UserContext.getUserId());
        boolean result = save(moment);
        AssertUtils.isTrue(result, "创建Moment失败");
        return moment.getId();
    }

    @Override
    public ResponsePage<MomentVo> listMoment(MomentListRequest request) {
        String startTime = null;
        String endTime = null;

        if (StringUtils.isNotBlank(request.getTime())) {
            String time = request.getTime();
            // 判断是年份（如 "2025"）还是年月（如 "2025-11"）
            if (time.length() == 4) {
                // 年份格式：2025-01-01 到 2026-01-01
                startTime = time + "-01-01";
                endTime = (Integer.parseInt(time) + 1) + "-01-01";
            } else {
                // 年月格式：2025-11-01 到 2025-12-01
                startTime = time + "-01";
                endTime = YearMonth.parse(time).plusMonths(1).atDay(1).toString();
            }
        }

        Page<Moment> page = page(new Page<>(request.getPageNo(), request.getPageSize()), Wrappers.<Moment>lambdaQuery()
                .eq(Boolean.TRUE.equals(request.getIsFavorite()), Moment::getIsFavorite, true)
                .ge(startTime != null, Moment::getCreatedTime, startTime)
                .lt(endTime != null, Moment::getCreatedTime, endTime)
                .orderByDesc(Moment::getCreatedTime));
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return ResponsePage.ok();
        }

        return ResponsePage.ok(page, page.getRecords().stream()
                .map(o -> BaseHelper.r2t(o, MomentVo.class))
                .collect(Collectors.toList()));
    }

    @Override
    public MomentVo detailsMoment(Long id) {
        Moment moment = getById(id);
        AssertUtils.notNull(moment, "Moment不存在");
        return BaseHelper.r2t(moment, MomentVo.class);
    }

    @Override
    @Transactional
    public void updateMoment(Long id, MomentRequest request) {
        Moment moment = getById(id);
        AssertUtils.notNull(moment, "Moment不存在");

        BeanUtils.copyProperties(request, moment);
        boolean result = updateById(moment);
        AssertUtils.isTrue(result, "Moment更新失败");
    }

    @Override
    public MomentsFilterVo filter() {
        List<Moment> moments = list();

        Map<String, Integer> tagMap = new HashMap<>();
        Map<String, Integer> timeMap = new HashMap<>();

        moments.forEach(o -> {
//            if (StringUtils.isNotBlank(o.getTags())) {
//                for (String tag : JSON.parseArray(o.getTags(), String.class)) {
//                    tagMap.merge(tag, 1, Integer::sum);
//                }
//            }
            timeMap.merge(o.getCreatedTime().format(DateTimeFormatter.ofPattern("yyyy-MM")), 1, Integer::sum);
        });

        return MomentsFilterVo.builder()
                .tags(tagMap.keySet().stream()
                        .sorted(Comparator.comparing(tagMap::get).reversed())
                        .map(o -> new MomentsFilterVo.Item(o, tagMap.get(o)))
                        .collect(Collectors.toList()))
                .times(timeMap.keySet().stream()
                        .sorted(Comparator.reverseOrder())
                        .map(o -> new MomentsFilterVo.Item(o, timeMap.get(o)))
                        .collect(Collectors.toList()))
                .build();
    }

    @Override
    @Transactional
    public void deleteMoment(Long id) {
        boolean result = removeById(id);
        AssertUtils.isTrue(result, "删除失败");
    }

    @Override
    public MomentVo randomMoment() {
        // 获取当前用户的所有moment数量
        long count = count(Wrappers.<Moment>lambdaQuery()
                .eq(Moment::getUserId, UserContext.getUserId()));
        AssertUtils.isTrue(count > 0, "暂无数据");

        // 生成随机偏移量
        long offset = (long) (Math.random() * count);

        // 查询一条随机记录
        Page<Moment> page = page(new Page<>(offset + 1, 1),
                Wrappers.<Moment>lambdaQuery()
                        .eq(Moment::getUserId, UserContext.getUserId())
                        .orderByDesc(Moment::getCreatedTime));

        AssertUtils.isTrue(CollectionUtils.isNotEmpty(page.getRecords()), "获取随机Moment失败");

        return BaseHelper.r2t(page.getRecords().get(0), MomentVo.class);
    }

    @Override
    public List<CreatedTimeListVo> listCreatedTime() {
        List<Moment> moments = list(Wrappers.<Moment>lambdaQuery().orderByDesc(Moment::getCreatedTime));
        Map<String, Map<String, Integer>> map = new HashMap<>();

        moments.forEach(o -> {
            String year = o.getCreatedTime().format(DateTimeFormatter.ofPattern("yyyy"));
            String month = o.getCreatedTime().format(DateTimeFormatter.ofPattern("yyyy-MM"));

            Map<String, Integer> months = map.get(year);
            if (months == null) {
                months = new HashMap<>();
            }

            months.merge(month, 1, Integer::sum);
            map.put(year, months);
        });

        return map.entrySet().stream()
                .sorted(Map.Entry.<String, Map<String, Integer>>comparingByKey().reversed())
                .map(yearEntry -> {
                    CreatedTimeListVo yearVo = new CreatedTimeListVo();
                    yearVo.setTime(yearEntry.getKey());
                    // 计算年份下所有月份的数量总和
                    yearVo.setNum(yearEntry.getValue().values().stream().mapToInt(Integer::intValue).sum());

                    // 月份子节点，按时间逆序
                    List<CreatedTimeListVo> monthList = yearEntry.getValue().entrySet().stream()
                            .sorted(Map.Entry.<String, Integer>comparingByKey().reversed())
                            .map(monthEntry -> {
                                CreatedTimeListVo monthVo = new CreatedTimeListVo();
                                monthVo.setTime(monthEntry.getKey());
                                monthVo.setNum(monthEntry.getValue());
                                monthVo.setChildren(null);
                                return monthVo;
                            }).collect(Collectors.toList());
                    yearVo.setChildren(monthList);
                    return yearVo;
                }).collect(Collectors.toList());
    }
}